package rediscli

import (
	"context"
	"fmt"
	"go-ws-server/utils"
	"log"
	"time"

	"go-ws-server/model/dto"

	"github.com/redis/go-redis/v9"
)

type GetMessageListResp struct {
	ID         int64  `json:"id"`
	Title      string `json:"title"`
	SendType   string `json:"sendType"`
	Content    string `json:"content"`
	SendTime   string `json:"sendTime"`
	ReadStatus int    `json:"readStatus"`
}

type MessageDetails struct {
	ID          string `json:"id" gorm:"column:id"`
	Title       string `json:"title" gorm:"column:title"`
	Content     string `json:"content" gorm:"column:content"`
	Format      string `json:"format" gorm:"column:format"`
	SendType    string `json:"sendType" gorm:"column:send_type"`
	SendTime    string `json:"sendTime" gorm:"column:send_time"`
	CreatedTime string `json:"createdTime" gorm:"column:created_time"`
	UserID      string `json:"userId" gorm:"column:user_id"`
	AcceptID    string `json:"acceptId" gorm:"column:accept_id"`
	MessageID   string `json:"messageId" gorm:"column:message_id"`
	ReadStatus  string `json:"readStatus" gorm:"column:read_status"`
	Deleted     string `json:"deleted" gorm:"column:deleted"`
	ReceiveTime string `json:"receiveTime" gorm:"column:receive_time"`
}

var (
	Ctx = context.Background()
	Rdb *redis.Client
)

func InitRedis() {
	Rdb = redis.NewClient(&redis.Options{
		Addr:     "47.120.60.61:6379", // Redis 地址
		Password: "123456",            // 如果没有密码就留空
		DB:       0,                   // 默认 DB 0
	})

	_, err := Rdb.Ping(Ctx).Result()
	if err != nil {
		log.Fatalf("Redis 连接失败: %v", err)
	} else {
		log.Println("✅ Redis 连接成功")
	}
}

// 根据用户 ID 查询用户消息信息
func GetMessageListByUserID(ctx context.Context, rdb *redis.Client, userID string) ([]GetMessageListResp, error) {
	listKey := fmt.Sprintf("user_messages:%s", userID)

	// 取出该用户所有消息ID列表
	messageIDs, err := rdb.LRange(ctx, listKey, 0, -1).Result()

	if err != nil {
		return nil, fmt.Errorf("获取用户消息ID列表失败: %w", err)
	}

	log.Println("该用户所有消息ID列表:", messageIDs)

	var messages []GetMessageListResp

	for _, msgIDStr := range messageIDs {
		hashKey := fmt.Sprintf("user_message:%s:%s", userID, msgIDStr)

		fields, err := rdb.HGetAll(ctx, hashKey).Result()

		if err != nil {
			// 获取hash失败，继续处理下一条
			continue
		}
		if len(fields) == 0 {
			// 该消息hash可能已过期或不存在，跳过
			continue
		}

		hashKey1 := fmt.Sprintf("message:%s", fields["message_id"])

		fields1, err := rdb.HGetAll(ctx, hashKey1).Result()

		log.Println("user_message消息为：%v", fields)

		log.Println("message消息为：%v", fields1)

		var msg GetMessageListResp

		// 解析字段
		if v, ok := fields1["id"]; ok {
			fmt.Sscanf(v, "%d", &msg.ID)
		}
		//消息标题
		msg.Title = fields1["title"]
		//消息类型
		msg.SendType = fields1["send_type"]
		//消息内容
		msg.Content = fields1["content"]
		//发送时间
		output, err := utils.FormatTimeString(fields1["send_time"])
		if err != nil {
			fmt.Println("错误:", err)
		}
		msg.SendTime = output
		if v, ok := fields["read_status"]; ok {
			fmt.Sscanf(v, "%d", &msg.ReadStatus)
		}

		messages = append(messages, msg)
	}

	return messages, nil
}

// 根据消息ID 查询消息详情
func GetMessageDetail(ctx context.Context, rdb *redis.Client, messageId string, userId string) (MessageDetails, error) {

	hashKey1 := fmt.Sprintf("message:%s", messageId)

	fields1, err := rdb.HGetAll(ctx, hashKey1).Result()

	if err != nil {
		log.Fatalf("获取消息详情失败: %v", err)
	}

	log.Println("fields1=", fields1)

	var messageInfo MessageDetails

	messageInfo.Title = fields1["title"]        //标题
	messageInfo.Content = fields1["content"]    //消息体
	messageInfo.SendType = fields1["send_type"] //消息类型
	output, err := utils.FormatTimeString(fields1["send_time"])
	if err != nil {
		fmt.Println("错误:", err)
	}
	messageInfo.SendTime = output //发送时间
	output1, err := utils.FormatTimeString(fields1["created_time"])
	if err != nil {
		fmt.Println("错误:", err)
	}
	messageInfo.CreatedTime = output1 //创建时间

	hashKey := fmt.Sprintf("user_message:%s:%s", userId, messageId)
	log.Println("hashKey:", hashKey)
	result, err := rdb.HGetAll(ctx, hashKey).Result()
	if err != nil {
		if err == redis.Nil {
			log.Println("Key 不存在")
		} else {
			log.Fatal("Redis 错误:", err)
		}
	}
	log.Println("result:", result)
	messageInfo.UserID = result["user_id"]
	messageInfo.AcceptID = result["accept_id"]
	messageInfo.MessageID = result["message_id"]
	messageInfo.ReadStatus = result["read_status"]
	messageInfo.Deleted = result["deleted"]
	output2, err := utils.FormatTimeString(fields1["receive_time"])
	if err != nil {
		fmt.Println("错误:", err)
	}
	messageInfo.ReceiveTime = output2

	log.Println("消息详情：", messageInfo)
	return messageInfo, nil
}

// 写入单条 Message 到 Redis Hash
func WriteSingleMessageToRedis(msg dto.Message) error {
	key := fmt.Sprintf("message:%d", msg.ID)

	fields := map[string]interface{}{
		"id":           msg.ID,
		"title":        msg.Title,
		"send_type":    msg.SendType,
		"content":      msg.Content,
		"send_time":    msg.SendTime.Format(time.RFC3339),
		"created_time": msg.CreatedTime.Format(time.RFC3339),
	}

	pipe := Rdb.Pipeline()
	pipe.HSet(Ctx, key, fields)
	pipe.Expire(Ctx, key, 24*time.Hour)

	if _, err := pipe.Exec(Ctx); err != nil {
		return fmt.Errorf("写入 message:%d 到 Redis 失败: %w", msg.ID, err)
	}
	log.Printf("✅ 写入单条消息 message:%d 到 Redis 成功", msg.ID)
	return nil
}

// 写入单条 UserMessage 到 Redis Hash
func WriteSingleUserMessageToRedis(um dto.UserMessage) error {
	if um.UserID == "" {
		return fmt.Errorf("UserMessage.UserID 不能为空")
	}

	listKey := fmt.Sprintf("user_messages:%s", um.AcceptID)
	hashKey := fmt.Sprintf("user_message:%s:%d", um.AcceptID, um.MessageID)

	fields := map[string]interface{}{
		"id":           um.ID,
		"user_id":      um.UserID,
		"message_id":   um.MessageID,
		"read_status":  um.ReadStatus,
		"deleted":      um.Deleted,
		"receive_time": um.ReceiveTime.Format(time.RFC3339),
		"accept_id":    um.AcceptID,
	}

	pipe := Rdb.Pipeline()

	// 防止重复：先检查是否已经存在 message_id
	// 可选：如果你明确允许重复则可去掉此逻辑
	exists, err := Rdb.LPos(Ctx, listKey, fmt.Sprintf("%d", um.MessageID), redis.LPosArgs{}).Result()
	if err == redis.Nil || exists < 0 {
		// 不存在才添加
		pipe.RPush(Ctx, listKey, um.MessageID)
		pipe.Expire(Ctx, listKey, 24*time.Hour)
	}

	pipe.HSet(Ctx, hashKey, fields)
	pipe.Expire(Ctx, hashKey, 24*time.Hour)

	if _, err := pipe.Exec(Ctx); err != nil {
		return fmt.Errorf("写入 user_message:%s:%d 到 Redis 失败: %w", um.UserID, um.MessageID, err)
	}
	log.Printf("✅ 写入单条用户消息 user_message:%s:%d 到 Redis 成功", um.UserID, um.MessageID)
	return nil
}
